<?php
namespace App\Services\AfterSales;
use App\Common\BnFormatConfig;
use App\Common\Constant;
use App\Common\ResponseCode;
use App\Common\Tools;
use App\Exceptions\BusinessException;
use App\Params\Backend\AfterSalesApplyAuditParams;
use App\Params\Backend\AfterSalesApplyListParams;
use App\Params\H5\AfterSalesApplyParams;
use App\Params\H5\AfterSalesListParams;
use App\Repository\AfterSalesRepository;
use App\Repository\CustomerRepository;
use App\Repository\OrderItemRepository;
use App\Repository\OrderRepository;
use App\Services\BaseService;
use App\Traits\DateTimeTrait;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 售后相关业务类
 *
 * @author WangBin
 * @date 2021-09-24
 * @package App\Http\Services
 */
class AfterSalesService extends BaseService
{
    use DateTimeTrait;

    /**
     * 获取售后商品信息
     *
     * @param int $orderId
     * @param int $productId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object
     * @throws BusinessException
     */
    public function getGoods(int $orderId, int $productId)
    {
        $orderItem = OrderItemRepository::getInstance()->getByOrderAndProduct($orderId, $productId);
        if(is_null($orderItem)) {
            throw new BusinessException(ResponseCode::GOODS_NOT_FOUND);
        }
        return $orderItem;
    }

    /**
     * 申请售后
     *
     * @param AfterSalesApplyParams $params
     * @return int|mixed
     * @throws BusinessException
     */
    public function apply(AfterSalesApplyParams $params)
    {
        // 获取申请售后的订单明细
        $orderItem = OrderItemRepository::getInstance()->getByOrderAndProduct($params->getOrderId(), $params->getProductId());
        if(is_null($orderItem)) {
            throw new BusinessException(ResponseCode::GOODS_NOT_FOUND);
        }
        // 是否可以申请售后
        if($orderItem->is_aftersales == 1) {
            throw new BusinessException(ResponseCode::AFTERSALES_APPLY_FORBIDDEN_FAIL);
        }

        // 获取客户
        $customer = CustomerRepository::getInstance()->getById($params->getCustomerId());
        // 获取订单
        $order = OrderRepository::getInstance()->getById($params->getOrderId());

        try {
            DB::beginTransaction();
            // 写入申请售后记录
            $data = [
                'state' => Constant::AFTERSALES_APPLY_STATE_WAIT_AUDIT,
                'type' => $params->getType(),
                'customer_id' => $params->getCustomerId(),
                'customer_name' => $customer->nickname,
                'order_id' => $params->getOrderId(),
                'order_bn' => $order->order_bn,
                'apply_bn' => Tools::buildBn(BnFormatConfig::AFTERSALES_APPLY_BN_KEY),
                'total_qty' => $orderItem->qty_ordered,
                'total_amount' => $orderItem->total_amount,
                'images' => $params->getImages(),
                'content' => $params->getContent()
            ];
            $applyId = AfterSalesRepository::getInstance()->save($data);
            // 写入单据明细
            $item = [
                [
                    'apply_id' => $applyId,
                    'goods_id' => $orderItem->goods_id,
                    'product_id' => $orderItem->product_id,
                    'name' => $orderItem->name,
                    'qty' => $orderItem->qty_ordered,
                    'price' => $orderItem->price,
                    'image_url' => $orderItem->image_url,
                    'total_amount' => $orderItem->total_amount,
                    'specs' => $orderItem->specs,
                    'unit' => $orderItem->unit,
                    ]
            ];
            AfterSalesRepository::getInstance()->saveItem($item);

            // 更新订单明细已售后标识为 1
            OrderItemRepository::getInstance()->update(['is_aftersales' => 1], $orderItem->item_id);
            DB::commit();
            return $applyId;
        } catch (\Exception $exception) {
            DB::rollBack();
            Log::error("[申请售后] 出错：{$exception->getMessage()}");
            throw new BusinessException(ResponseCode::AFTERSALES_APPLY_FAIL);
        }
    }

    /**
     * 获取申请单列表
     *
     * @param AfterSalesApplyListParams $params
     * @return array
     */
    public function getList(AfterSalesApplyListParams $params)
    {
        $applyList = AfterSalesRepository::getInstance()->getList($params->toArray());
        $result = $this->toList($applyList, $params->getPage(), $params->getPageSize());
        collect($result['list'])->each(function ($item){
            $item->state_name = Constant::AFTERSALES_APPLY_STATE_MAP[$item->state];
            $item->actions = ['aftersales-list::audit', 'aftersales-list::view'];
        });
        return $result;
    }

    /**
     * 获取客户售后申请列表
     *
     * @param AfterSalesListParams $params
     * @return array
     */
    public function getH5List(AfterSalesListParams $params)
    {
        $applyList = AfterSalesRepository::getInstance()->getList($params->toArray());
        $result = $this->toList($applyList, $params->getPage(), $params->getPageSize());
        collect($result['list'])->each(function ($item) {
            $item->state_name = Constant::AFTERSALES_APPLY_STATE_MAP[$item->state];
        });
        return $result;
    }

    /**
     * 审核通过
     *
     * @param AfterSalesApplyAuditParams $params
     * @return int|mixed
     * @throws BusinessException
     */
    public function auditApply(AfterSalesApplyAuditParams $params)
    {
        // 获取售后申请单
        $apply = AfterSalesRepository::getInstance()->getApplyById($params->getApplyId());
        if(is_null($apply)) {
            throw new BusinessException(ResponseCode::AFTERSALES_APPLY_NOT_FOUND);
        }
        // 是否可以审核
        if($apply->state != Constant::BIZ_STATE_WAIT_AUDIT) {
            throw new BusinessException(ResponseCode::AFTERSALES_APPLY_AUDIT_ERROR);
        }
        $data = ['state' => $params->getState(), 'audited_at' => $this->getCurrDateTime(), 'audited_by' => $params->getUserName(), 'audit_opinion' => $params->getAuditOpinion()];
        $ret = AfterSalesRepository::getInstance()->save($data, $params->getApplyId());
        // 审核后的操作
        switch ($params->getState())
        {
            case Constant::BIZ_STATE_APPROVED:
                // 审核通过
                if($apply->type == Constant::AFTERSALES_APPLY_TYPE_RETURN) {
                    // 生产退货单、退款单
                }
                if($apply->type == Constant::AFTERSALES_APPLY_TYPE_EXCHANGE) {
                    // 生产退货单
                }
                break;
            case Constant::BIZ_STATE_REFUSED:
                // 审核拒绝
                // 如果是审核拒绝则需要将订单明细的 已申请售后 标识 改为 0 ，这个逻辑待定 todo
                break;
        }
        return $ret;
    }

    /**
     * 获取客户售后申请单详情
     *
     * @param int $applyId
     * @param int $customerId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getH5Detail(int $applyId, int $customerId)
    {
        $ret = AfterSalesRepository::getInstance()->getApplyById($applyId);
        $ret->state_name = Constant::AFTERSALES_APPLY_STATE_MAP[$ret->state];
        return $ret;
    }
}
